﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;

namespace festivalDatabase
{

    /// <summary>
    /// Class which creates a new festival in the database
    /// </summary>
    public partial class newFestival : userInterface
    {

        /// <summary>
        /// Creates the new festival GUI using the database accessor tables class. It 
        /// contains two boxes which let you choose between creating a Music or Art 
        /// festival
        /// </summary>
        /// <param name="db"> class which contains tables</param>
        public newFestival(dbAccessor db)
        {
            InitializeComponent();
            setIcon();
            dbAccess = db;
            festivalTypeComboBox.Items.Add("Music");
            festivalTypeComboBox.Items.Add("Art");
        }

        /// <summary>
        /// Handles the events which occur when the createFestivalButton is clicked and therefore
        /// creates a festival. It first verifies that the entry field is not empty and that it
        /// contains unique/valid fields for ID, date, end date.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void createFestivalButton_Click(object sender, EventArgs e)
        {
            errorProvider.Clear();
            successLabel.Visible = false;

            if (festivalIDMaskedTextBox.Text.ToString() != "" && verifyFestivalIDLength())
            {
                if (verifyUniqueFestivalID())
                {
                    if (verifyValidStartDate())
                    {
                        if (verifyValidEndDate())
                        {
                            if (festivalTypeComboBox.Text != "Music" && festivalTypeComboBox.Text != "Art")
                                errorProvider.SetError(festivalTypeComboBox, "Invalid festival type; please select a type from the dropdown.");
                            else
                            {
                                createFestival();
                                successLabel.Visible = true;
                                this.Close();
                                System.Windows.Forms.MessageBox.Show("Festival added successfully.");

                            }
                        }
                        else
                            errorProvider.SetError(endDateMaskedTextBox, "Invalid end date. Please enter a valid date in the form mm/dd/yyyy and ensure date is after start date.");
                    }
                    else
                        errorProvider.SetError(startDateMaskedTextBox, "Invalid start date. Please enter a valid date in the form mm/dd/yyyy.");
                }
                else
                    errorProvider.SetError(festivalIDMaskedTextBox, "Festival ID is not unique.");
            }
            else
                errorProvider.SetError(festivalIDMaskedTextBox, "Festival ID must be 4 numbers long.");
            
        }

        /// <summary>
        /// Verifies that the festival ID is unique in the database, so no duplicates may exist.
        /// </summary>
        /// <returns> bool </returns>
        private bool verifyUniqueFestivalID()
        {
            SQLiteCommand query = dbAccess.getCommand();
            query.CommandText = "SELECT id " +
                                "FROM festival;";

            DataTable dt = dbAccess.executeQuery(query);
            foreach (DataRow row in dt.Rows)
            {
                if (row["id"].ToString() == festivalIDMaskedTextBox.Text.ToString())
                    return false;
            }
            return true;
        }

        /// <summary>
        /// Verifies that the length of the festival ID is valid and fits the constraints of being 4 digits long
        /// </summary>
        /// <returns> bool </returns>
        private bool verifyFestivalIDLength()
        {
            char[] festivalIDInput = festivalIDMaskedTextBox.Text.ToCharArray();
            int intCount = 0;

            for (int i = 0; i < festivalIDInput.Length; i++)
            {
                if (festivalIDInput[i] == '0' || festivalIDInput[i] == '1' || festivalIDInput[i] == '2' || festivalIDInput[i] == '3' || festivalIDInput[i] == '4' || festivalIDInput[i] == '5' || festivalIDInput[i] == '6' || festivalIDInput[i] == '7' || festivalIDInput[i] == '8' || festivalIDInput[i] == '9')
                    intCount++;
            }

            if (intCount == 4)
                return true;
            else
                return false;
        }

        /// <summary>
        /// Verifies that the start date for the festival is a correct, valid date which is limited
        /// to ten characters, so it fits within  the constraints.
        /// </summary>
        /// <returns> bool </returns>
        private bool verifyValidStartDate()
        {
            if (startDateMaskedTextBox.Text.Length == 10)
            {
                try
                {
                    DateTime date = DateTime.Parse(startDateMaskedTextBox.Text.ToString());
                    if (date.Month > 12)
                        return false;
                    if (date.Day > 31)
                        return false;
                }
                catch
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Verifies that the start date for the festival is a correct, valid date which is limited
        /// to ten characters, so it fits within  the constraints.
        /// </summary>
        /// <returns> bool </returns>
        private bool verifyValidEndDate()
        {
            if (endDateMaskedTextBox.Text.Length == 10)
            {
                try
                {
                    DateTime endDate = DateTime.Parse(endDateMaskedTextBox.Text.ToString());
                    DateTime startDate = DateTime.Parse(startDateMaskedTextBox.Text.ToString());

                    if (endDate.Month > 12)
                        return false;
                    if (endDate.Day > 31)
                        return false;
                    if (endDate.Month < startDate.Month && endDate.Year <= startDate.Year)
                        return false;
                    if (endDate.Month == startDate.Month && endDate.Year == startDate.Year)
                        if (endDate.Day < startDate.Day)
                            return false;
                }
                catch
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Method directly responsible for inserting the start date, end date, location, festival type, and
        /// id into the backend SQL database. These all come from input fields which the user enters.
        /// </summary>
        private void createFestival()
        {
            SQLiteCommand nonQuery = dbAccess.getCommand();

            nonQuery.CommandText = "INSERT INTO festival(";
            nonQuery.CommandText += "id";
            if (festivalNameTextBox.Text.ToString() != "")
                nonQuery.CommandText += ", name";
            if (startDateMaskedTextBox.Text.Length == 10)
                nonQuery.CommandText += ", start_date";
            if (endDateMaskedTextBox.Text.Length == 10)
                nonQuery.CommandText += ", end_date";
            if (locationTextBox.Text.ToString() != "")
                nonQuery.CommandText += ", location";
            if (festivalTypeComboBox.SelectedIndex >= 0)
                nonQuery.CommandText += ", festival_type";

            nonQuery.CommandText += ") VALUES (@Id";
            nonQuery.Parameters.Add("@Id", DbType.Int16);
            nonQuery.Parameters["@Id"].Value = festivalIDMaskedTextBox.Text.ToString();
            if (festivalNameTextBox.Text.ToString() != "")
            {
                nonQuery.CommandText += ", @Name";
                nonQuery.Parameters.Add("@Name", DbType.String);
                nonQuery.Parameters["@Name"].Value = festivalNameTextBox.Text.ToString();
            }
            if (startDateMaskedTextBox.Text.Length == 10)
            {
                nonQuery.CommandText += ", @Start";
                nonQuery.Parameters.Add("@Start", DbType.DateTime);
                nonQuery.Parameters["@Start"].Value = DateTime.Parse(startDateMaskedTextBox.Text.ToString());
            }
            if (endDateMaskedTextBox.Text.Length == 10)
            {
                nonQuery.CommandText += ", @End";
                nonQuery.Parameters.Add("@End", DbType.DateTime);
                nonQuery.Parameters["@End"].Value = DateTime.Parse(endDateMaskedTextBox.Text.ToString());
            }
            if (locationTextBox.Text.ToString() != "")
            {
                nonQuery.CommandText += ", @Location";
                nonQuery.Parameters.Add("@Location", DbType.String);
                nonQuery.Parameters["@Location"].Value = locationTextBox.Text.ToString();
            }
            if (festivalTypeComboBox.Text.Length > 0)
            {
                nonQuery.CommandText += ", @Type";
                nonQuery.Parameters.Add("@Type", DbType.String);
                nonQuery.Parameters["@Type"].Value = festivalTypeComboBox.Text.ToString();
            }
            nonQuery.CommandText += ");";
            dbAccess.executeNonQuery(nonQuery);
        }
    }
}
